import { Component, ReactNode } from 'react'

interface Props {
  children: ReactNode
  fallback?: ReactNode
  onError?: (error: Error, errorInfo: React.ErrorInfo) => void
}

interface State {
  hasError: boolean
  error: Error | null
}

/**
 * 错误边界组件
 * 捕获子组件的错误，防止整个应用崩溃
 */
export class ErrorBoundary extends Component<Props, State> {
  constructor(props: Props) {
    super(props)
    this.state = { hasError: false, error: null }
  }

  static getDerivedStateFromError(error: Error): State {
    return { hasError: true, error }
  }

  componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {
    console.error('ErrorBoundary 捕获到错误:', error, errorInfo)
    this.props.onError?.(error, errorInfo)
    
    // 生产环境发送到监控服务
    if (import.meta.env.PROD) {
      // 这里可以集成 Sentry 等监控服务
      // Sentry.captureException(error, {
      //   contexts: {
      //     react: {
      //       componentStack: errorInfo.componentStack
      //     }
      //   }
      // })
    }
  }

  render() {
    if (this.state.hasError) {
      return this.props.fallback || (
        <div className="min-h-screen flex items-center justify-center bg-dark-500 p-4">
          <div className="glass-effect-dark rounded-2xl p-8 max-w-md w-full text-center border border-red-500/30">
            <div className="text-6xl mb-4">😔</div>
            <h2 className="text-2xl font-bold text-white mb-2">
              出错了
            </h2>
            <p className="text-gray-400 mb-6">
              {this.state.error?.message || '应用遇到了一个问题'}
            </p>
            <div className="flex flex-col sm:flex-row gap-3 justify-center">
              <button
                onClick={() => window.location.reload()}
                className="px-6 py-3 bg-gradient-to-r from-accent-purple to-accent-blue text-white rounded-lg hover:scale-105 transition-transform"
              >
                刷新页面
              </button>
              <button
                onClick={() => this.setState({ hasError: false, error: null })}
                className="px-6 py-3 bg-white/10 text-white rounded-lg hover:bg-white/20 transition-colors"
              >
                重试
              </button>
            </div>
          </div>
        </div>
      )
    }

    return this.props.children
  }
}

/**
 * 特定功能的错误回退UI
 */
export function ModelErrorFallback({ 
  error, 
  resetError 
}: { 
  error?: Error
  resetError?: () => void 
}) {
  return (
    <div className="glass-effect-dark rounded-2xl p-6 border border-red-500/30">
      <div className="text-center">
        <div className="text-6xl mb-4">🚫</div>
        <h3 className="text-xl font-bold text-white mb-2">模型加载失败</h3>
        <p className="text-gray-400 text-sm mb-4">
          {error?.message || '无法加载 3D 模型，请重试'}
        </p>
        {resetError && (
          <button
            onClick={resetError}
            className="px-4 py-2 bg-red-500/20 text-red-400 rounded-lg hover:bg-red-500/30 transition-colors"
          >
            重试
          </button>
        )}
      </div>
    </div>
  )
}

/**
 * 网络错误回退UI
 */
export function NetworkErrorFallback({ retry }: { retry?: () => void }) {
  return (
    <div className="flex flex-col items-center justify-center py-12">
      <div className="text-6xl mb-4">📡</div>
      <h3 className="text-xl font-bold text-white mb-2">网络连接失败</h3>
      <p className="text-gray-400 text-sm mb-4">请检查您的网络连接</p>
      {retry && (
        <button
          onClick={retry}
          className="px-6 py-3 bg-gradient-to-r from-accent-blue to-accent-cyan text-white rounded-lg hover:scale-105 transition-transform"
        >
          重新加载
        </button>
      )}
    </div>
  )
}

